/**
 *
 */
package com.honeybees.framework.common.util;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;

/**
 * <dl>
 * <dt><b> 标题 </b></dt>
 * <p>
 * <dd>功能描述</dd>
 * </dl>
 * <p>
 * Copyright (C) All rights reserved.
 * </p>
 *
 * @author 李远明
 * @since 2016年7月20日 上午10:43:52
 */
public final class Utils {

    /**
     * 电子邮箱地址格式正则表达式
     */
    public static final String REGEX_EMAIL = "^([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)*@([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[\\.][A-Za-z]{2,3}([\\.][A-Za-z]{2})?$";

    /**
     * 手机格式正则表达式
     */
    public static final String REGEX_MOBILE_PHONE_NO = "^((861)|(1))\\d{10}$";

    /**
     * 身份证格式正则表达式
     */
    public static final String REGEX_IDENT_NUMBER = "^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$";

    /**
     *
     */
    private final static byte[] HEX = "0123456789abcdef".getBytes();

    /**
     * <dl>
     * <dt><b> 将字符串转换成 int 类型，默认为0。 </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @param str
     * @return
     * @author 李远明
     * @version 2016年4月28日 上午11:21:36
     */
    public static int safeToInt(Object str) {
        String ss = String.valueOf(str);
        int val = 0;
        try {
            val = Integer.parseInt(ss);
        } catch (NumberFormatException e) {
            val = 0;
        }
        return val;
    }

    /**
     * <dl>
     * <dt><b> 将字符串转换成 {@link Integer} 类型，默认为null。 </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @param str
     * @return
     * @author 李远明
     * @version 2016年4月28日 上午11:23:32
     */
    public static Integer safeToInteger(Object str) {
        String ss = String.valueOf(str);
        Integer val = 0;
        try {
            val = Integer.parseInt(ss);
        } catch (NumberFormatException e) {
            val = null;
        }
        return val;
    }

    /**
     * <dl>
     * <dt><b> 将名字中间部分用点号代替 </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @param text
     *            字符串
     * @return
     * @author 李远明
     * @version 2016-05-26 14:37:15
     */
    public static String abbrText(String text) {
        if (StringUtils.isBlank(text)) {
            return text;
        }
        int length = text.length();

        int retainLen = length;
        String middle = "*";

        if (length >= 20) {
            retainLen = length / 2 - 4;
            middle = buildMid(retainLen);
        } else if (length >= 10) {
            retainLen = length / 2;
            middle = buildMid(retainLen);
        } else {
            retainLen = length / 2 + 2;
            middle = buildMid(retainLen);
        }
        String vagueName = StringUtils.abbreviateMiddle(text, middle, retainLen);
        return vagueName;
    }

    private static String buildMid(int length) {
        StringBuilder sb = new StringBuilder(length / 2);
        for (int i = 0; i < length / 2; i++) {
            sb.append("*");
        }
        return sb.toString();
    }

    /**
     * 验证手机号码是否符合基本格式
     *
     * @param mobile
     * @return
     */
    public static boolean isMobilePhoneNo(String mobile) {
        Pattern p = Pattern.compile(REGEX_MOBILE_PHONE_NO);
        Matcher m = p.matcher(mobile);
        return m.matches();
    }

    /**
     * 验证邮箱是否符合格式
     *
     * @param email
     * @return
     */
    public static boolean isEmail(String email) {
        Pattern p = Pattern.compile(REGEX_EMAIL);
        Matcher m = p.matcher(email);
        return m.matches();
    }

    /**
     * 验证身份证是否符合格式
     *
     * @param idNumber
     * @return
     */
    public static boolean isIdentNumber(String idNumber) {
        Pattern p = Pattern.compile(REGEX_IDENT_NUMBER);
        Matcher m = p.matcher(idNumber);
        return m.matches();
    }

    /**
     * <dl>
     * <dt><b> 4位十六进制随机数 </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @return
     * @author 李远明
     * @version 2016年7月22日 下午3:00:36
     */
    public static String rnd4() {
        double d1 = 1 + Math.random();
        double d2 = 65536 * d1;
        double d3 = Math.floor(d2);
        String hexString = Integer.toString((int) d3, 16);
        return hexString.substring(1);
    }

    /**
     * <dl>
     * <dt><b> 不含横线的UUID </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @return
     * @author 李远明
     * @version 2016年7月22日 下午3:00:46
     */
    public static String shortUUID() {
        return rnd4() + rnd4() + rnd4() + rnd4() + rnd4() + rnd4() + rnd4() + rnd4();
    }

    /**
     * <dl>
     * <dt><b> 含有横线的UUID </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @return
     * @author 李远明
     * @version 2016年7月22日 下午3:00:49
     */
    public static String longUUID() {
        return rnd4() + rnd4() + "-" + rnd4() + "-" + rnd4() + "-" + rnd4() + "-" + rnd4() + rnd4() + rnd4();
    }

    /**
     * <dl>
     * <dt><b> 十六进制编码 </b></dt>
     * <p>
     * <dd>将byte数组转换为十六进制字符串</dd>
     * </dl>
     *
     * @param bytes
     *            byte数组
     * @return 十六进制字符串
     * @author 李远明
     * @version 2016-08-08 11:23:46
     */
    // public static String bytes2hex(byte[] bytes) {
    // StringBuilder hex = new StringBuilder();
    // for (byte b : bytes) {
    // boolean negative = false; // 是否为负数
    // if (b < 0) {
    // negative = true;
    // }
    // int inta = Math.abs(b);
    // if (negative) {
    // inta = inta | 0x80;
    // }
    // // 负数转换为正数（最高位的负号变成数值计算），再转成十六进制
    // String hexString = Integer.toHexString(inta & 0xff);
    // if (hexString.length() == 1) {
    // hex.append('0');
    // }
    // hex.append(hexString);
    // }
    // return hex.toString();
    // }
    public static String bytes2hex(byte[] bytes) {
        int l = 0;
        if (bytes != null && bytes.length != 0) {
            l = bytes.length;
        }
        byte[] buff = new byte[2 * bytes.length];
        for (int i = 0; i < l; i++) {
            buff[2 * i] = HEX[(bytes[i] >> 4) & 0x0f];
            buff[2 * i + 1] = HEX[bytes[i] & 0x0f];
        }
        return new String(buff);
    }

    /**
     * <dl>
     * <dt><b> 十六进制解码 </b></dt>
     * <p>
     * <dd>将十六进制字符串转换为byte数组</dd>
     * </dl>
     *
     * @param hexString
     *            十六进制字符串
     * @return byte数组
     * @author 李远明
     * @version 2016-08-08 11:30:29
     */
    // public static byte[] hex2bytes(String hexString) {
    // byte[] bytes = new byte[hexString.length() / 2];
    // for (int i = 0, l = hexString.length(); i < l; i = i + 2) {
    // String substring = hexString.substring(i, i + 2);
    // int inta = Integer.parseInt(substring, 16);
    // boolean negative = false; // 是否为负数
    // if (inta > 127) {
    // negative = true;
    // }
    // if (inta == 128) {
    // inta = -128;
    // } else if (negative) {
    // inta = 0 - (inta & 0x7f);
    // }
    // byte b = (byte) inta;
    // bytes[i / 2] = b;
    // }
    // return bytes;
    // }
    public static byte[] hex2bytes(String hexString) {
        int len = 0;
        if (hexString != null && hexString.length() != 0) {
            len = hexString.length();
        }
        byte[] bytes = new byte[len / 2];
        int j = 0;
        for (int i = 0, l = bytes.length; i < l; i++) {
            char c0 = hexString.charAt(j++);
            char c1 = hexString.charAt(j++);
            bytes[i] = (byte) ((convert(c0) << 4) | convert(c1));
        }
        return bytes;
    }

    private static int convert(char c) {
        if (c >= 'a') {
            int i = (c - 'a' + 10) & 0x0f;
            return i;
        }
        if (c >= 'A') {
            int i = (c - 'A' + 10) & 0x0f;
            return i;
        }
        int i = (c - '0') & 0x0f;
        return i;
    }

    /**
     * <dl>
     * <dt><b> 数据转换 </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @param x
     * @return
     * @author 李远明
     * @version 2016-08-17 13:13:56
     */
    public static byte[] int2byte(int x) {
        byte[] dest = new byte[4];
        dest[3] = (byte) (x & 0xff); // 最低位
        dest[2] = (byte) ((x >> 8) & 0xff); // 次低位
        dest[1] = (byte) ((x >> 16) & 0xff); // 次高位
        dest[0] = (byte) (x >>> 24); // 最高位，无符号右移
        return dest;
    }

    /**
     * <dl>
     * <dt><b> 数据转换 </b></dt>
     * <p>
     * <dd>将4个 byte 转换为 int 值</dd>
     * </dl>
     *
     * @param b1
     * @param b2
     * @param b3
     * @param b4
     * @return
     * @author 李远明
     * @version 2016-08-17 13:17:31
     */
    public static int byte2int(byte b1, byte b2, byte b3, byte b4) {
        int x = ((b1 & 0xff) << 24) | ((b2 & 0xff) << 16) | ((b3 & 0xff) << 8) | (b4 & 0xff);
        return x;
    }

    /**
     * <dl>
     * <dt><b> 获取2个值之间的随机数 </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @param min
     *            第一个数
     * @param max
     *            第二个数
     * @return 随机数
     * @author 李远明
     * @version 2016-08-18 14:26:34
     */
    public static int randomNum(int min, int max) {
        int range = max - min;
        double rand = Math.random();
        long round = Math.round(rand * range);
        int value = (int) (round + min);
        return (value);
    }

    public static void main(String[] args) {
        byte[] bytes = new byte[] { -1, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 7, -128, 0, 0, 4,
                56, 8, 6, 0, 0 }; // PNG
        String bytes2hex = bytes2hex(bytes);
        System.out.println("bytes2hex: " + bytes2hex);
        String hex2bytes = Arrays.toString(hex2bytes(bytes2hex));
        System.out.println("hex2bytes: " + hex2bytes);

        String encodeHexString = Hex.encodeHexString(bytes);
        System.out.println(encodeHexString);
    }

}
